import hashlib
import random
import string
from xml.etree import ElementTree

import requests
import time

# 微信支付商户号配置（请替换为你的实际配置）
APPID = 'your_appid'  # 小程序appid; appid是微信公众账号或开放平台APP的唯一标识，在公众平台申请公众账号或者在开放平台申请APP账号后，微信会自动分配对应的appid，用于标识该应用。
MCHID = 'your_mch_id'  # 微信支付商户号 商户申请微信支付后，由微信支付分配的商户收款账号。
API_KEY = 'your_api_key'  # API密钥	key	交易过程生成签名的密钥，仅保留在商户系统和微信支付后台，设置路径：pay.weixin.qq.com /账户设置/安全/密钥设置
NOTIFY_URL = 'https://ggok.top/api/hello_api/wxpay_notify'  # 支付结果通知回调URL


# AppSecret是APPID对应的接口密码，用于获取接口调用凭证access_token时使用。在微信支付中，先通过OAuth2.0接口获取用户openid，此openid用于微信内网页支付模式下单接口使用。在开发模式中获取AppSecret（成为开发者且帐号没有异常状态）。


# 生成随机字符串
def generate_nonce_str(length=32):
    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))


# 生成签名
def generate_signature(params, key):
    sorted_params = sorted(params.items())
    string_a = '&'.join(f'{k}={v}' for k, v in sorted_params)
    string_sign_temp = f'{string_a}&key={key}'
    return hashlib.sha256(string_sign_temp.encode('utf-8')).hexdigest().upper()


# 微信支付统一下单接口
def unified_order(out_trade_no, total_fee, body, spbill_create_ip):
    nonce_str = generate_nonce_str()
    params = {
        'appid': APPID,
        'mch_id': MCHID,
        'nonce_str': nonce_str,
        'body': body,
        'out_trade_no': out_trade_no,
        'total_fee': total_fee,  # 单位：分
        'spbill_create_ip': spbill_create_ip,
        'notify_url': NOTIFY_URL,
        'trade_type': 'JSAPI',  # 公众号支付
        'openid': 'user_openid',  # 用户的openid，这里需要替换为实际用户的openid
    }
    params['sign'] = generate_signature(params, API_KEY)

    xml_data = ElementTree.Element('xml')
    for key, value in params.items():
        sub_element = ElementTree.SubElement(xml_data, key)
        sub_element.text = str(value)

    xml_str = ElementTree.tostring(xml_data, encoding='utf-8').decode('utf-8')

    url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
    res = requests.post(url, data=xml_str, headers={'Content-Type': 'application/xml'})
    return res.content


# 示例调用
if __name__ == '__main__':
    out_trade_no = f'order_{int(time.time() * 1000)}_{random.randint(1000, 9999)}'
    total_fee = 1  # 1分钱
    body = 'Test Order'
    spbill_create_ip = '123.12.12.123'  # 用户终端IP，这里需要替换为实际用户的IP
    response = unified_order(out_trade_no, total_fee, body, spbill_create_ip)
    print(response)
